在上一篇《Javascript Promises模式——相当酷的Callback Hell终结者》 我们介绍了Javascript的Promise模式,接着我们就把Javascript Promise用到我们的代码中。
JavaScript Promise库 Q
之前试着用过Q,但是没有成功。或者说,在那时候不需要用上Q,所以没有深究。现在抱着学习的态度,重新试了一下,效果还不错。
A tool for making and composing asynchronous promises in JavaScript
Q是一个提供制作和创作异步Promise的JavaScript工具。Q 提供了一些辅助函数,可以将Node和其他环境适配为promise可用的。
JavaScript Promise库 Q示例
官网给了一个简单的转换的例子
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
将他转换为
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
但是,我们没有看懂,我们到底做了些什么。。
JavaScript Promise 库 Q实战
原生的代码是这样子的,用的是async库
async.parallel([
function () {
'use strict';
pr.get(domain, next);
},
function () {
'use strict';
gs.get(name, next);
},
function () {
'use strict';
csdn.get(name, next);
},
function () {
'use strict';
zhihu.get(name, next);
},
function () {
'use strict';
alexa.get(domain, next);
}
]);
但是总感觉写得有点乱,不过至少离开了所谓的回调大坑。
过程大致上就是当我们需要不断往我们的result里面添加东西。
于是将代码改成Promise的形式,接着就变成这样了
github.promise_get(response, name)
.then(function (result) {
return pr.promise_get(result, domain);
})
.then(function (result) {
return csdn.promise_get(result, name);
})
.then(function (result) {
return zhihu.promise_get(result, name);
})
.then(function (result) {
return alexa.promise_get(result, domain);
})
.then(function (result) {
callback(result);
});
但是这样看上去写得有点不好,因为我们将过程固化在代码中,于是试着,用别的方法对其重构。
重构的第一步后就变成这样子
var info = Information.prototype;
info.pageRank_get = function(result){
'use strict';
return pageRank.promise_get(result, Information.prototype.domain);
};
info.alexa_get = function(result){
'use strict';
return alexa.promise_get(result, Information.prototype.domain);
};
info.csdn_get= function (result) {
'use strict';
return csdn.promise_get(result, info.name);
};
info.github_get= function (result) {
'use strict';
return github.promise_get(result, info.name);
};
info.zhihu_get = function (result) {
'use strict';
return zhihu.promise_get(result, info.name);
};
info.initVal = function (result) {
'use strict';
result = [];
return result;
};
Information.prototype.get = function (callback) {
'use strict';
Q.fcall(info.initVal)
.then(info.github_get)
.then(info.csdn_get)
.then(info.zhihu_get())
.then(info.pageRank_get)
.then(info.alexa_get)
.then(function (result) {
callback(result);
});
};
先提出每一个方法,然后我们就可以选择我们需要用到的库。看上去比上面整洁多了,但是我们还需要下一步,以便继续。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。